package cn.aezo.minions.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * @author smalle
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> implements Serializable {
    private static final String META_STATUS_SUCCESS = "success";
    private static final String META_STATUS_ERROR = "error";
    private static final Integer META_CODE_SUCCESS = 20000;
    private static final Integer META_CODE_ERROR = 40000;

    private String metaStatus;
    private String metaMessage;
    private T data;
    private Integer metaCode;
    private String metaCodeKey;
    private List metaErrors;
    private long timestamp = System.currentTimeMillis();

    public static boolean isSuccess(Result result) {
        return (result != null && Result.META_STATUS_SUCCESS.equals(result.getMetaStatus()));
    }

    public static boolean isError(Result result) {
        return !isSuccess(result);
    }

    public static Long getLongValue(Map<String, Object> context, String key) {
        if(context == null) {
            return null;
        }
        Object obj = context.get(key);
        if(obj == null) {
            return null;
        }
        if(obj instanceof Long) {
            return (Long) obj;
        } else if(obj instanceof Integer || obj instanceof String) {
            return Long.valueOf(obj + "");
        } else {
            throw new IllegalStateException("Illegal Long Key: " + key);
        }
    }

    public static Result success() {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_SUCCESS;
        result.metaCode = Result.META_CODE_SUCCESS;
        return result;
    }

    public static Result success(String metaMessage) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_SUCCESS;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_SUCCESS;
        return result;
    }

    public static <T> Result success(T data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_SUCCESS;
        result.metaCode = Result.META_CODE_SUCCESS;
        result.data = data;
        return result;
    }

    public static <T> Result success(String metaMessage, T data) {
        Result result = new Result<>();
        result.metaStatus = Result.META_STATUS_SUCCESS;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_SUCCESS;
        result.data = data;
        return result;
    }

    public static Result failure() {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaCode = Result.META_CODE_ERROR;
        return result;
    }

    public static Result failure(String metaMessage) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        return result;
    }

    public static Result failure(String metaMessage, String metaCodeKey) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        result.metaCodeKey = metaCodeKey;
        return result;
    }

    public static Result failure(String metaMessage, Integer metaCode) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = metaCode;
        return result;
    }

    public static Result failure(String metaMessage, Map<String, Object> data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        result.data = data;
        return result;
    }

    public static <T> Result failure(String metaMessage, T data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        result.data = data;
        return result;
    }

    public static <T> Result failure(String metaMessage, String metaCodeKey, T data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        result.metaCodeKey = metaCodeKey;
        result.data = data;
        return result;
    }

    public static <T> Result failure(String metaMessage, List metaErrors, T data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.metaCode = Result.META_CODE_ERROR;
        result.metaErrors = metaErrors;
        result.data = data;
        return result;
    }

    public static <T> Result failure(String metaMessage, Integer metaCode, String metaCodeKey, List metaErrors, T data) {
        Result result = new Result();
        result.metaStatus = Result.META_STATUS_ERROR;
        result.metaMessage = metaMessage;
        result.data = data;
        result.metaCode = metaCode;
        result.metaCodeKey = metaCodeKey;
        result.metaErrors = metaErrors;
        return result;
    }
}